{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 我们共创建如下类：\n",
    "# - MapController \n",
    "#   负责管理地图\n",
    "#   * 允许生成、输出、加载地图信息\n",
    "#   * 允许生成、输出、加载各服务设备的特征向量\n",
    "#   * 通过用户位置生成用户特征变量\n",
    "#   * 允许输入完整路径来获取全过程的用户特征向量\n",
    "# - PathController\n",
    "#   负责管理用户路径\n",
    "#   * 通过 Random Waypoint 算法生成用户路径\n",
    "#   * 允许给定时隙数量、速度范围、地图范围生成完整路径\n",
    "#   * 允许输出和加载完整路径\n",
    "# - TaskController\n",
    "#   负责管理任务数据\n",
    "#   * 给定时隙总数和间隔数（任务类型切换），生成任务序列\n",
    "# - OPTAlgorithm\n",
    "#   基于最短路的离线最优算法\n",
    "#   * 输入完整的任务信息、用户特征\n",
    "# - OnlineAlgorithmController\n",
    "#   控制在线算法并对其结果进行测算的控制类\n",
    "#   * 输入完整的任务信息和用户特征，分时隙提供给在线算法\n",
    "import numpy as np\n",
    "import math\n",
    "from matplotlib import pyplot as plt \n",
    "np.random.seed(1314)\n",
    "\n",
    "# 注意：我们假设每个设备信号可以覆盖临近的\n",
    "\n",
    "class MapController:\n",
    "    def __init__(self, mapSize, devicePositions):\n",
    "        print('---Map Controller Initializing---')\n",
    "        self.mapSize = mapSize\n",
    "        self.S = self.mapSize * self.mapSize\n",
    "        self.M = len(devicePositions)\n",
    "        self.deviceRange = np.zeros((len(devicePositions), mapSize * mapSize), dtype=np.int)\n",
    "        for index, position in enumerate(devicePositions):\n",
    "            self.deviceRange[index][position[0] * mapSize + position[1]] = 1\n",
    "            if position[0] > 0:\n",
    "                if position[1] > 0:\n",
    "                    self.deviceRange[index][position[0] * mapSize + position[1] - mapSize - 1] = 3\n",
    "                self.deviceRange[index][position[0] * mapSize + position[1] - mapSize] = 2\n",
    "                if position[1] < (mapSize - 1):\n",
    "                    self.deviceRange[index][position[0] * mapSize + position[1] - mapSize + 1] = 3\n",
    "            if position[0] < (mapSize - 1):\n",
    "                if position[1] > 0:\n",
    "                    self.deviceRange[index][position[0] * mapSize + position[1] + mapSize - 1] = 3\n",
    "                self.deviceRange[index][position[0] * mapSize + position[1] + mapSize] = 2\n",
    "                if position[1] < (mapSize - 1):\n",
    "                    self.deviceRange[index][position[0] * mapSize + position[1] + mapSize + 1] = 3\n",
    "            if position[1] > 0:\n",
    "                self.deviceRange[index][position[0] * mapSize + position[1] - 1] = 2\n",
    "            if position[1] < (mapSize - 1):\n",
    "                self.deviceRange[index][position[0] * mapSize + position[1] + 1] = 2\n",
    "            if position[0] > 1:\n",
    "                self.deviceRange[index][position[0] * mapSize + position[1] - 2 * mapSize] = 4\n",
    "            if position[0] < (mapSize - 2):\n",
    "                self.deviceRange[index][position[0] * mapSize + position[1] + 2 * mapSize] = 4\n",
    "            if position[1] > 1:\n",
    "                self.deviceRange[index][position[0] * mapSize + position[1] - 2] = 4\n",
    "            if position[1] < (mapSize - 2):\n",
    "                self.deviceRange[index][position[0] * mapSize + position[1] + 2] = 4\n",
    "        print('---Map Controller Initialized---')\n",
    "\n",
    "    # task: [计算负载，传输负载，上下文数据量, 上下文部署延时]\n",
    "    # at: 当前任务部署位置，为 index（0为本地，1为云端，2～M+1为边缘设备）\n",
    "    def get_b(self, task, position, at):\n",
    "        M = self.M\n",
    "        S = self.S\n",
    "        G = np.zeros((M+S+1,1))\n",
    "        F = np.zeros((M+S+1,1))\n",
    "        G[position] = 1\n",
    "        if at == 0:\n",
    "            F[position] = 1\n",
    "        else:\n",
    "            F[S-1+at] = 1\n",
    "        b = np.zeros((3*M+3*S+4,1))\n",
    "        b[0,0] = task[0]\n",
    "        b[1:M+S+2] = task[1] * G + task[2] * F\n",
    "        b[M+S+2:2*M+2*S+3] = G + F\n",
    "        b[2*M+2*S+3:] = task[3] * F\n",
    "        return b\n",
    "\n",
    "    def get_zts(self, positions):\n",
    "        print('---MC: Generating zts---')\n",
    "        zts = []\n",
    "        for position in positions:\n",
    "            zt = np.zeros(self.M+2)\n",
    "            zt[:2] = 1\n",
    "            zt[2:] = (self.deviceRange.T[position] > 0).astype('int')\n",
    "            zts.append(zt)\n",
    "        print('---MC: Zts generated---')\n",
    "        return zts               \n",
    "\n",
    "    # 注意：所有的计算能力单位为 MHz  \n",
    "    # 注意：所有的通信能力单位为 Mbps\n",
    "    def get_mus(self, TCount, \n",
    "        # 计算能力\n",
    "        DCapacityMin, DCapacityMax,\n",
    "        CCapacityMin, CCapacityMax, LCapacityMin, LCapacityMax,\n",
    "        # 基础延时\n",
    "        D2DBaseDelay, CellularBaseDelayMin, CellularBaseDelayMax,\n",
    "        CloudBaseDelayMin, CloudBaseDelayMax,\n",
    "        # 传输速率\n",
    "        D2DNSpdMins, D2DNSpdMaxs, Spd2Device, Spd2Cloud, \n",
    "        positions):\n",
    "        print('---MC: Generating mus---')\n",
    "        print('- Time slot count:', TCount)\n",
    "        print('-- Computing Capacity Parameters --')\n",
    "        print('- Device Computing Capacity Range:', DCapacityMin, '-', DCapacityMax)\n",
    "        print('- Cloud Computing Capacity Range:', CCapacityMin, '-', CCapacityMax)\n",
    "        print('- Local Computing Capacity Range:', LCapacityMin, '-', LCapacityMax)\n",
    "        print('-- Base Delay Parameters --')\n",
    "        print('- D2D Base Delay:', D2DBaseDelay)\n",
    "        print('- Cellular Base Delay Range:', CellularBaseDelayMin, '-', CellularBaseDelayMax)\n",
    "        print('- Cloud Base Delay Range:', CloudBaseDelayMin, '-', CloudBaseDelayMax)\n",
    "        print('-- Transmission Speed Parameters --')\n",
    "        print('- D2D Speed Mins:', D2DNSpdMins)\n",
    "        print('- D2D Speed Maxs:', D2DNSpdMaxs)\n",
    "        print('- Speed between D2D devices:', Spd2Device)\n",
    "        print('- Speed to cloud device', Spd2Cloud)\n",
    "        M = self.M\n",
    "        S = self.S\n",
    "        mus = []\n",
    "        positionRange = self.deviceRange.T\n",
    "        for time in range(TCount):\n",
    "            must = []\n",
    "            # 生成设备-本地传输速率矩阵\n",
    "            SpdMatrix = Spd2Device * np.ones((S,M))\n",
    "            for i in range(1, 5):\n",
    "                SpdMatrix[positionRange == i] = np.random.uniform(D2DNSpdMins[i], D2DNSpdMaxs[i], np.sum(positionRange == i))\n",
    "            # 生成设备-本地基础延时矩阵\n",
    "            baseMatrix = D2DBaseDelay * np.ones((S,M))\n",
    "            baseMatrix[positionRange == 0] = np.random.uniform(CellularBaseDelayMin, CellularBaseDelayMax, np.sum(positionRange == 0))\n",
    "            # 生成设备-设备基础延时矩阵\n",
    "            dBaseMatrix = np.random.uniform(CellularBaseDelayMin, CellularBaseDelayMax, (M, M))\n",
    "            dBaseMatrix = np.triu(dBaseMatrix)\n",
    "            dBaseMatrix = dBaseMatrix + dBaseMatrix.T\n",
    "            # 生成云基础延时\n",
    "            cloudBase = np.random.uniform(CloudBaseDelayMin, CloudBaseDelayMax)\n",
    "\n",
    "            # 首先生成本地设备的特征\n",
    "            mu = np.zeros((3*M+3*S+4,1)) \n",
    "            mu[0,0] = 1/np.random.uniform(LCapacityMin, LCapacityMax) # 0 计算负载\n",
    "            # mu[1:S+1,0] = 0 # 1～S 到各位置本地设备的传输速率\n",
    "            mu[S+1,0] = 1/Spd2Cloud # S+1 到云端的传输速率\n",
    "            mu[S+2:S+2+M,0] = 1/SpdMatrix[positions[time]] # S+2～S+1+M 到各边缘设备的传输速率\n",
    "            # mu[S+2+M:2*S+2+M,0] = 0 # S+2+M～2*S+1+M 到本地的基础延时\n",
    "            mu[2*S+2+M,0] = cloudBase # 2*S+2+M 到云端的基础延时\n",
    "            mu[2*S+3+M:2*S+2*M+3,0] = baseMatrix[positions[time]] # 2*S+3+M ～ 2*S+2*M+2 到边缘设备的基础延时\n",
    "            mu[2*S+2*M+3:,] = 1 # 标记当前设备\n",
    "            mu[2*S+2*M+3+positions[time],0] = 0\n",
    "            must.append(mu)\n",
    "\n",
    "            # 然后生成云端设备的特征\n",
    "            mu = np.zeros((3*M+3*S+4,1))\n",
    "            mu[0,0] = 1/np.random.uniform(CCapacityMin, CCapacityMax)\n",
    "            mu[1:S+1,0] = 1/Spd2Cloud\n",
    "            mu[S+1,0] = 0\n",
    "            mu[S+2:S+2+M,0] = 1/Spd2Cloud\n",
    "            mu[S+2+M:2*S+2+M,0] = cloudBase\n",
    "            mu[2*S+2+M,0] = 0\n",
    "            mu[2*S+3+M:2*S+2*M+3,0] = cloudBase\n",
    "            mu[2*S+2*M+3:,] = 1\n",
    "            mu[3*S+2*M+3,0] = 0\n",
    "            must.append(mu)\n",
    "\n",
    "            # 最后生成边缘设备的特征\n",
    "            for i in range(M):\n",
    "                mu = np.zeros((3*M+3*S+4,1))\n",
    "                mu[0,0] = 1/np.random.uniform(DCapacityMin, DCapacityMax)\n",
    "                mu[1:S+1,0] = 1/(SpdMatrix.T[i])\n",
    "                mu[S+1,0] = 1/Spd2Cloud\n",
    "                mu[S+2:S+2+M,0] = 1/Spd2Device\n",
    "                mu[S+2+M:2*S+2+M,0] = baseMatrix.T[i]\n",
    "                mu[2*S+2+M,0] = cloudBase\n",
    "                mu[2*S+3+M:2*S+2*M+3,0] = dBaseMatrix[i]\n",
    "                mu[2*S+2*M+3:,] = 1\n",
    "                mu[3*S+2*M+4+i,0] = 0\n",
    "                must.append(mu)\n",
    "\n",
    "            # 将当前时隙的 mu 加入总 mus\n",
    "            mus.append(must)\n",
    "        print('---MC: Mus generated---')\n",
    "        return mus\n",
    "\n",
    "class PathController:\n",
    "    def __init__(self):\n",
    "        print('---Path Controller Initialized---')\n",
    "\n",
    "    def getPath(self, MinSpd, MaxSpd, PMax, TCount, mapSize):\n",
    "        print('---PC: Generating user mobility with RWP---')\n",
    "        print('- Minimal Speed:', MinSpd, ', Maximal Speed:', MaxSpd)\n",
    "        print('- Maximal Pause Time:', PMax, ', Map Size:', mapSize)\n",
    "        print('- Time of mobility:', TCount)\n",
    "        positionFloat = np.zeros(2)\n",
    "        positions = []\n",
    "        count = 0\n",
    "\n",
    "\n",
    "        while count < TCount:\n",
    "            # 获取目标位置\n",
    "            targetPosition = np.random.uniform(0, mapSize, 2)\n",
    "            # 获取单位方向向量\n",
    "            directionVec = targetPosition - positionFloat\n",
    "            directionVec = directionVec / np.linalg.norm(directionVec)\n",
    "            # 获取速度\n",
    "            currentSpd = np.random.uniform(MinSpd, MaxSpd)\n",
    "            \n",
    "            while True:\n",
    "                if count > TCount:\n",
    "                    break\n",
    "                if np.linalg.norm(positionFloat - targetPosition) < currentSpd:\n",
    "                    count = count + 1\n",
    "                    if count > TCount:\n",
    "                        break\n",
    "                    positionFloat = targetPosition\n",
    "                    tempPos = positionFloat.astype('int')\n",
    "                    positions.append(tempPos[0] * mapSize + tempPos[1])\n",
    "                    pauseTime = int(np.random.uniform(0, PMax))\n",
    "                    for _ in range(pauseTime):\n",
    "                        count = count + 1\n",
    "                        if count > TCount:\n",
    "                            break\n",
    "                        tempPos = positionFloat.astype('int')\n",
    "                        positions.append(tempPos[0] * mapSize + tempPos[1])\n",
    "                    break\n",
    "                count = count + 1\n",
    "                positionFloat = positionFloat + directionVec * currentSpd\n",
    "                tempPos = positionFloat.astype('int')\n",
    "                positions.append(tempPos[0] * mapSize + tempPos[1])\n",
    "        print('---PC: User mobility generated---')            \n",
    "        return positions  \n",
    "\n",
    "class TaskController:\n",
    "    # 计算负载单位：Cycles/Mbits（10000M/2500M/250M）\n",
    "    # 传输负载单位：Mbps（2000/40/8）\n",
    "    # 切换上下文数据：1000M/10M/0\n",
    "    # 切换延时指标：0～10ms\n",
    "    def get_tasks(self, compute, transmit, switchC, switchDMax,\n",
    "        TCount, interval):\n",
    "        print('---TC: Generating tasks---')\n",
    "        print('- Computing Demand Type:', compute)\n",
    "        print('- Transmission Demand Type:', transmit)\n",
    "        print('- Context transmission demand type:', switchC)\n",
    "        print('- Max Switch Deployment Time:', switchDMax)\n",
    "        NCompute = len(compute)\n",
    "        NTransmit = len(transmit)\n",
    "        NSwitchC = len(switchC)\n",
    "        count = 0\n",
    "        tasks = []\n",
    "        while count < TCount:\n",
    "            computeIndex = int(np.random.uniform(0, NCompute))\n",
    "            transmitIndex = int(np.random.uniform(0, NTransmit))\n",
    "            switchCIndex = int(np.random.uniform(0, NSwitchC))\n",
    "            switchD = np.random.uniform(0, switchDMax)\n",
    "            for i in range(interval):\n",
    "                count = count + 1\n",
    "                tasks.append((compute[computeIndex], transmit[transmitIndex],\n",
    "                    switchC[switchCIndex], switchD))\n",
    "                if count >= TCount:\n",
    "                    break\n",
    "        print('---TC: Tasks generated---')\n",
    "        return tasks\n",
    "\n",
    "class OPTAlgorithm:\n",
    "    def __init__(self, tasks, mu, z, NStep, positions, M, MC):\n",
    "        print('---Offline Optimal Algorithm Initializing---')\n",
    "        self.tasks = tasks\n",
    "        self.mu = mu\n",
    "        self.z = z\n",
    "        self.lastZ = np.zeros(M+2)\n",
    "        self.lastZ[0] = 1\n",
    "        self.minSums = [np.zeros(M+2)]\n",
    "        self.count = 0\n",
    "        self.positions = positions\n",
    "        self.NStep = NStep\n",
    "        self.M = M\n",
    "        self.MC = MC\n",
    "        print('---Offline Optimal Algorithm Initialized---')\n",
    "    \n",
    "    def step(self):\n",
    "        if self.count >= self.NStep:\n",
    "            print('---OOA: No more steps, fail to operate---')\n",
    "            return\n",
    "        bts = []\n",
    "        for (index, p) in enumerate(self.lastZ):\n",
    "            if p == 1:\n",
    "                bts.append((index, self.MC.get_b(self.tasks[self.count], self.positions[self.count], index)))\n",
    "        self.lastZ = self.z[self.count]\n",
    "        self.minSums.append(np.ones(self.M+2) * float('inf'))\n",
    "        for (index, p) in enumerate(self.z[self.count]):\n",
    "            if p == 1:\n",
    "                for (lastIndex, bt) in bts:\n",
    "                    r = self.evaluate(bt, self.mu[self.count][index])\n",
    "                    if r + self.minSums[-2][lastIndex] < self.minSums[-1][index]:\n",
    "                        self.minSums[-1][index] = r + self.minSums[-2][lastIndex]\n",
    "        self.count = self.count + 1\n",
    "        return np.min(self.minSums[-1])\n",
    "    \n",
    "    def run_all(self, gap):\n",
    "        print('---OOA: Running Optimal Algorithm---')\n",
    "        avg_cost = []\n",
    "        while self.count < self.NStep:\n",
    "            currentSum = self.step()\n",
    "            if self.count % gap == 0:\n",
    "                avg_cost.append(currentSum / self.count)\n",
    "            if self.count % 1000 == 0:\n",
    "                print('- Step:', self.count, '/', self.NStep)\n",
    "                print('- Current avg sum:', currentSum / self.count)\n",
    "        print('---OOA: Optimal Algorithm Finished---')\n",
    "        return avg_cost\n",
    "\n",
    "    def evaluate(self, bt, mu):\n",
    "        return bt.T@mu\n",
    "\n",
    "\n",
    "class OnlineAlgorithmController:\n",
    "    def __init__(self, algorithm, tasks, mu, z, NStep, positions, MC):\n",
    "        print('---Online Algorithm Controller Initializing---')\n",
    "        self.tasks = tasks\n",
    "        self.mu = mu\n",
    "        self.z = z\n",
    "        self.count = 0\n",
    "        self.NStep = NStep\n",
    "        self.algorithm = algorithm\n",
    "        self.positions = positions\n",
    "        self.MC = MC\n",
    "        self.at = 0\n",
    "        print('---Online Algorithm Controller Initialized---')\n",
    "        print('- Algorithm:', type(algorithm))\n",
    "        print('- Total steps:', NStep)\n",
    "\n",
    "    def step(self):\n",
    "        if self.count >= self.NStep:\n",
    "            print('---OAC: No more steps, fail to operate---')\n",
    "            return\n",
    "        self.b = self.MC.get_b(self.tasks[self.count], self.positions[self.count], self.at)\n",
    "        self.at = self.algorithm.choose(self.z[self.count], self.b)\n",
    "        r = self.evaluate()\n",
    "        self.algorithm.update(r, self.b)\n",
    "        # TODO: cumulate info and print the image\n",
    "        self.count = self.count + 1\n",
    "        return r[0][0]\n",
    "\n",
    "    def run_all(self, gap):\n",
    "        print('---OAC: Running algorithm', type(self.algorithm), '---')\n",
    "        sum = 0\n",
    "        avg_cost = []\n",
    "        while self.count < self.NStep:\n",
    "            sum += self.step()\n",
    "            if self.count % gap == 0:\n",
    "                avg_cost.append(sum / self.count)\n",
    "            if self.count % 1000 == 0:\n",
    "                print('- Step:', self.count, '/', self.NStep)\n",
    "                print('- Current avg sum:', sum / self.count)\n",
    "        print('---OAC: Algorithm', self.algorithm, 'finished---')\n",
    "        return avg_cost\n",
    "\n",
    "    \n",
    "    def evaluate(self):\n",
    "        if self.count >= self.NStep:\n",
    "            print('---OAC: No more steps, fail to operate---')\n",
    "            return -1\n",
    "        r = self.b.T@self.mu[self.count][self.at]\n",
    "        return r\n",
    "\n",
    "class LinUCB:\n",
    "    def __init__(self, M, S, alpha):\n",
    "        print('---LinUCB initializing---')\n",
    "        # 构造 Bi，Bi = B[i-1]\n",
    "        self.B = [np.identity(3*M+3*S+4) for count in range(1, M+3)]\n",
    "        # 构造 mui，mui = mu[i-1]\n",
    "        self.mu = [np.zeros((3*M+3*S+4,1)) for count in range(1, M+3)]\n",
    "        self.f = [np.zeros((3*M+3*S+4,1)) for count in range(1, M+3)]\n",
    "        self.alpha = alpha\n",
    "        self.selectIndex = 0\n",
    "        print('---LinUCB initialized---')\n",
    "\n",
    "    def choose(self, zt, bt):\n",
    "        minUCB = float('infinity')\n",
    "        for index, p in enumerate(zt):\n",
    "            if p == 1:\n",
    "                temp = bt.T @ self.mu[index] - self.alpha * math.sqrt(bt.T@self.B[index]@bt)\n",
    "                if (temp < minUCB)[0][0]:\n",
    "                    minUCB = temp\n",
    "                    self.selectIndex = index\n",
    "        return self.selectIndex\n",
    "\n",
    "    def update(self, r, bt):\n",
    "        self.f[self.selectIndex] = self.f[self.selectIndex] + r * bt\n",
    "        self.B[self.selectIndex] = self.B[self.selectIndex] + bt @ bt.T\n",
    "        self.mu[self.selectIndex] = np.linalg.inv(self.B[self.selectIndex]) @ self.f[self.selectIndex]\n",
    "\n",
    "class ThompsonSamping:\n",
    "    def __init__(self, M, S, v):\n",
    "        print('---TS initializing---')\n",
    "        # 构造 Bi，Bi = B[i-1]\n",
    "        self.B = [np.identity(3*M+3*S+4) for count in range(1, M+3)]\n",
    "        # 构造 mui，mui = mu[i-1]\n",
    "        self.mu = [np.zeros((3*M+3*S+4,1)) for count in range(1, M+3)]\n",
    "        self.f = [np.zeros((3*M+3*S+4,1)) for count in range(1, M+3)]\n",
    "        self.v = v\n",
    "        self.selectIndex = 0\n",
    "        print('---TS initialized---')\n",
    "\n",
    "    def choose(self, zt, bt):\n",
    "        minTS = float('infinity')\n",
    "        for index, p in enumerate(zt):\n",
    "            if p == 1:\n",
    "                temp = np.random.normal(bt.T@self.mu[index], self.v * np.sqrt(bt.T@np.linalg.inv(self.B[index])@bt))\n",
    "                if (temp < minTS)[0][0]:\n",
    "                    minTS = temp\n",
    "                    self.selectIndex = index\n",
    "        return self.selectIndex\n",
    "\n",
    "    def update(self, r, bt):\n",
    "        self.f[self.selectIndex] = self.f[self.selectIndex] + r * bt\n",
    "        self.B[self.selectIndex] = self.B[self.selectIndex] + bt @ bt.T\n",
    "        self.mu[self.selectIndex] = np.linalg.inv(self.B[self.selectIndex]) @ self.f[self.selectIndex]\n",
    "\n",
    "class PureRandom:\n",
    "    def __init__(self, M):\n",
    "        self.total = M + 2\n",
    "        print('---Pure Random initialized---')\n",
    "\n",
    "    def choose(self, zt, bt):\n",
    "        while True:\n",
    "            testIndex = int(np.random.uniform(0, self.total))\n",
    "            if zt[testIndex] == 1:\n",
    "                return testIndex\n",
    "\n",
    "    def update(self, r, bt):\n",
    "        pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------ 测试参数 ------- #\n",
    "# 地图大小 mapSize * mapSize\n",
    "mapSize = 5 \n",
    "# 边缘设备摆放位置\n",
    "devicePositions = [(0,0),(0,2),(0,4),\n",
    "                   (2,0),(2,2),(2,4),\n",
    "                   (4,0),(4,2),(4,4)]\n",
    "S = mapSize * mapSize\n",
    "M = len(devicePositions)\n",
    "\n",
    "# 测试时隙数\n",
    "TCount = 10000\n",
    "# 边缘计算能力（MHz）\n",
    "DCapacityMin = 10000\n",
    "DCapacityMax = 15000\n",
    "# 云端计算能力（MHz）\n",
    "CCapacityMin = 100000\n",
    "CCapacityMax = 120000\n",
    "# 本地计算能力（MHz）\n",
    "LCapacityMin = 1500\n",
    "LCapacityMax = 2500\n",
    "\n",
    "# 基础延时\n",
    "D2DBaseDelay = 0.1\n",
    "CellularBaseDelayMin = 0.5\n",
    "CellularBaseDelayMax = 5\n",
    "CloudBaseDelayMin = 50\n",
    "CloudBaseDelayMax = 100\n",
    "\n",
    "# 传输速率\n",
    "D2DNSpdMins = [0, 1000, 100, 50, 10]\n",
    "D2DNSpdMaxs = [0, 1500, 150, 75, 15]\n",
    "Spd2Device = 500\n",
    "Spd2Cloud = 500\n",
    "\n",
    "# 用户移动速度番位\n",
    "MinSpd = 0.5\n",
    "MaxSpd = 1.5\n",
    "# 用户最大停留时间\n",
    "PMax = 5\n",
    "\n",
    "# 计算负载单位：MCycles/Mbits（10000M/2500M/250M）\n",
    "compute = [100000, 10000, 2500, 250]\n",
    "# 传输负载单位：Mbps（2000/40/8）\n",
    "transmit = [2000, 40, 8]\n",
    "# 切换上下文数据：1000M/10M/0\n",
    "switchC = [1000, 10, 0]\n",
    "# 切换延时指标：0～10ms\n",
    "switchDMax = 10\n",
    "# 单任务持续时隙\n",
    "interval = 5\n",
    "\n",
    "# 算法参数\n",
    "# LinUCB\n",
    "alpha = 0.1\n",
    "# Thompson Samling\n",
    "v = 0.05"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "---Map Controller Initializing---\n",
      "---Map Controller Initialized---\n",
      "---Path Controller Initialized---\n",
      "---PC: Generating user mobility with RWP---\n",
      "- Minimal Speed: 0.5 , Maximal Speed: 1.5\n",
      "- Maximal Pause Time: 5 , Map Size: 5\n",
      "- Time of mobility: 10000\n",
      "---PC: User mobility generated---\n",
      "---TC: Generating tasks---\n",
      "- Computing Demand Type: [100000, 10000, 2500, 250]\n",
      "- Transmission Demand Type: [2000, 40, 8]\n",
      "- Context transmission demand type: [1000, 10, 0]\n",
      "- Max Switch Deployment Time: 10\n",
      "---TC: Tasks generated---\n",
      "---MC: Generating zts---\n",
      "---MC: Zts generated---\n",
      "---MC: Generating mus---\n",
      "- Time slot count: 10000\n",
      "-- Computing Capacity Parameters --\n",
      "- Device Computing Capacity Range: 10000 - 15000\n",
      "- Cloud Computing Capacity Range: 100000 - 120000\n",
      "- Local Computing Capacity Range: 1500 - 2500\n",
      "-- Base Delay Parameters --\n",
      "- D2D Base Delay: 0.1\n",
      "- Cellular Base Delay Range: 0.5 - 5\n",
      "- Cloud Base Delay Range: 50 - 100\n",
      "-- Transmission Speed Parameters --\n",
      "- D2D Speed Mins: [0, 1000, 100, 50, 10]\n",
      "- D2D Speed Maxs: [0, 1500, 150, 75, 15]\n",
      "- Speed between D2D devices: 500\n",
      "- Speed to cloud device 500\n",
      "---MC: Mus generated---\n",
      "---LinUCB initializing---\n",
      "---LinUCB initialized---\n",
      "---TS initializing---\n",
      "---TS initialized---\n",
      "---Pure Random initialized---\n",
      "---Online Algorithm Controller Initializing---\n",
      "---Online Algorithm Controller Initialized---\n",
      "- Algorithm: <class '__main__.LinUCB'>\n",
      "- Total steps: 10000\n",
      "---Online Algorithm Controller Initializing---\n",
      "---Online Algorithm Controller Initialized---\n",
      "- Algorithm: <class '__main__.ThompsonSamping'>\n",
      "- Total steps: 10000\n",
      "---Online Algorithm Controller Initializing---\n",
      "---Online Algorithm Controller Initialized---\n",
      "- Algorithm: <class '__main__.PureRandom'>\n",
      "- Total steps: 10000\n",
      "---Offline Optimal Algorithm Initializing---\n",
      "---Offline Optimal Algorithm Initialized---\n"
     ]
    }
   ],
   "source": [
    "# ----测试代码---- #\n",
    "\n",
    "# 构造 MapController\n",
    "mc = MapController(mapSize=5, devicePositions=devicePositions)\n",
    "# 构造 PathController\n",
    "pc = PathController()\n",
    "# 构造 TaskController\n",
    "tc = TaskController()\n",
    "# 获取用户移动路径\n",
    "positions = pc.getPath(MinSpd, MaxSpd, PMax, TCount, mapSize)\n",
    "# 获取任务数据\n",
    "tasks = tc.get_tasks(compute,transmit,switchC,switchDMax,TCount,interval)\n",
    "# 获取可用节点信息\n",
    "zts = mc.get_zts(positions)\n",
    "# 获取均值向量\n",
    "mus = mc.get_mus(TCount, \n",
    "    DCapacityMin, DCapacityMax, CCapacityMin, CCapacityMax, LCapacityMin, LCapacityMax,\n",
    "    D2DBaseDelay, CellularBaseDelayMin, CellularBaseDelayMax, CloudBaseDelayMin, CloudBaseDelayMax,\n",
    "    D2DNSpdMins, D2DNSpdMaxs, Spd2Device, Spd2Cloud,\n",
    "    positions)\n",
    "\n",
    "\n",
    "# 构造 算法类 和 OnlineAlgorithmController\n",
    "\n",
    "linUCB = LinUCB(M, S, alpha)\n",
    "ts = ThompsonSamping(M, S, v)\n",
    "pr = PureRandom(M)\n",
    "\n",
    "oacUCB = OnlineAlgorithmController(linUCB, tasks, mus, zts, TCount, positions, mc)\n",
    "oacTS  = OnlineAlgorithmController(ts, tasks, mus, zts, TCount, positions, mc)\n",
    "oacPR  = OnlineAlgorithmController(pr, tasks, mus, zts, TCount, positions, mc)\n",
    "ooa    = OPTAlgorithm(tasks, mus, zts, TCount, positions, M, mc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "---OOA: Running Optimal Algorithm---\n",
      "- Step: 1000 / 10000\n",
      "- Current avg sum: 6.173253022823718\n",
      "- Step: 2000 / 10000\n",
      "- Current avg sum: 6.711815836131855\n",
      "- Step: 3000 / 10000\n",
      "- Current avg sum: 6.775009901601271\n",
      "- Step: 4000 / 10000\n",
      "- Current avg sum: 6.783064755117597\n",
      "- Step: 5000 / 10000\n",
      "- Current avg sum: 6.675821575168818\n",
      "- Step: 6000 / 10000\n",
      "- Current avg sum: 6.667263788033815\n",
      "- Step: 7000 / 10000\n",
      "- Current avg sum: 6.696440396321644\n",
      "- Step: 8000 / 10000\n",
      "- Current avg sum: 6.573991135006288\n",
      "- Step: 9000 / 10000\n",
      "- Current avg sum: 6.6206403856098\n",
      "- Step: 10000 / 10000\n",
      "- Current avg sum: 6.635628244914231\n",
      "---OOA: Optimal Algorithm Finished---\n",
      "---OAC: Running algorithm <class '__main__.LinUCB'> ---\n",
      "- Step: 1000 / 10000\n",
      "- Current avg sum: 13.273754579582658\n",
      "- Step: 2000 / 10000\n",
      "- Current avg sum: 14.79671806426499\n",
      "- Step: 3000 / 10000\n",
      "- Current avg sum: 14.66022215419782\n",
      "- Step: 4000 / 10000\n",
      "- Current avg sum: 14.807838077920492\n",
      "- Step: 5000 / 10000\n",
      "- Current avg sum: 14.738145103847678\n",
      "- Step: 6000 / 10000\n",
      "- Current avg sum: 14.681806357838603\n",
      "- Step: 7000 / 10000\n",
      "- Current avg sum: 14.909350536139234\n",
      "- Step: 8000 / 10000\n",
      "- Current avg sum: 14.541994860854283\n",
      "- Step: 9000 / 10000\n",
      "- Current avg sum: 14.55778614936817\n",
      "- Step: 10000 / 10000\n",
      "- Current avg sum: 14.630431158976362\n",
      "---OAC: Algorithm <__main__.LinUCB object at 0x1034dc4e0> finished---\n",
      "---OAC: Running algorithm <class '__main__.ThompsonSamping'> ---\n",
      "- Step: 1000 / 10000\n",
      "- Current avg sum: 20.549021286713106\n",
      "- Step: 2000 / 10000\n",
      "- Current avg sum: 16.53798552260313\n",
      "- Step: 3000 / 10000\n",
      "- Current avg sum: 14.636114342547021\n",
      "- Step: 4000 / 10000\n",
      "- Current avg sum: 13.64070363526109\n",
      "- Step: 5000 / 10000\n",
      "- Current avg sum: 12.988562325133138\n",
      "- Step: 6000 / 10000\n",
      "- Current avg sum: 12.247574322941514\n",
      "- Step: 7000 / 10000\n",
      "- Current avg sum: 11.963429131187477\n",
      "- Step: 8000 / 10000\n",
      "- Current avg sum: 11.481963417791432\n",
      "- Step: 9000 / 10000\n",
      "- Current avg sum: 11.242883699133213\n",
      "- Step: 10000 / 10000\n",
      "- Current avg sum: 11.00524948721129\n",
      "---OAC: Algorithm <__main__.ThompsonSamping object at 0x1034dc9e8> finished---\n",
      "---OAC: Running algorithm <class '__main__.PureRandom'> ---\n",
      "- Step: 1000 / 10000\n",
      "- Current avg sum: 61.130006636533174\n",
      "- Step: 2000 / 10000\n",
      "- Current avg sum: 62.34449547200525\n",
      "- Step: 3000 / 10000\n",
      "- Current avg sum: 63.473112748224395\n",
      "- Step: 4000 / 10000\n",
      "- Current avg sum: 63.445863011224716\n",
      "- Step: 5000 / 10000\n",
      "- Current avg sum: 63.615505355660865\n",
      "- Step: 6000 / 10000\n",
      "- Current avg sum: 63.7691056219605\n",
      "- Step: 7000 / 10000\n",
      "- Current avg sum: 63.77341072029844\n",
      "- Step: 8000 / 10000\n",
      "- Current avg sum: 63.51257288367118\n",
      "- Step: 9000 / 10000\n",
      "- Current avg sum: 63.34166276444812\n",
      "- Step: 10000 / 10000\n",
      "- Current avg sum: 63.23090206320407\n",
      "---OAC: Algorithm <__main__.PureRandom object at 0x1034dcdd8> finished---\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "gap = 100\n",
    "\n",
    "cost_ooa = ooa.run_all(gap)\n",
    "cost_ucb = oacUCB.run_all(gap)\n",
    "cost_ts  = oacTS.run_all(gap)\n",
    "cost_pr  = oacPR.run_all(gap)\n",
    "\n",
    "xs = range(gap, gap + TCount, gap)\n",
    "\n",
    "plt.title('Result Analysis')\n",
    " \n",
    "plt.plot(xs, cost_ucb,  color='#1177b0', label='LinUCB')\n",
    "plt.plot(xs, cost_ts, color='#45b787', label='Thompson Sampling')\n",
    "plt.plot(xs, cost_pr, color='#ad9e5f', label='Pure Random')\n",
    "plt.plot(xs, cost_ooa,color='#61649f', label='Offline Optimal')\n",
    "plt.legend()\n",
    " \n",
    "plt.xlabel('Learning Slot')\n",
    "plt.ylabel('Average Time Cost')\n",
    "plt.savefig('resultAlgorithm.png')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "---TS initializing---\n",
      "---TS initialized---\n",
      "---TS initializing---\n",
      "---TS initialized---\n",
      "---TS initializing---\n",
      "---TS initialized---\n",
      "---TS initializing---\n",
      "---TS initialized---\n",
      "---TS initializing---\n",
      "---TS initialized---\n",
      "---TS initializing---\n",
      "---TS initialized---\n",
      "---Online Algorithm Controller Initializing---\n",
      "---Online Algorithm Controller Initialized---\n",
      "- Algorithm: <class '__main__.ThompsonSamping'>\n",
      "- Total steps: 10000\n",
      "---Online Algorithm Controller Initializing---\n",
      "---Online Algorithm Controller Initialized---\n",
      "- Algorithm: <class '__main__.ThompsonSamping'>\n",
      "- Total steps: 10000\n",
      "---Online Algorithm Controller Initializing---\n",
      "---Online Algorithm Controller Initialized---\n",
      "- Algorithm: <class '__main__.ThompsonSamping'>\n",
      "- Total steps: 10000\n",
      "---Online Algorithm Controller Initializing---\n",
      "---Online Algorithm Controller Initialized---\n",
      "- Algorithm: <class '__main__.ThompsonSamping'>\n",
      "- Total steps: 10000\n",
      "---Online Algorithm Controller Initializing---\n",
      "---Online Algorithm Controller Initialized---\n",
      "- Algorithm: <class '__main__.ThompsonSamping'>\n",
      "- Total steps: 10000\n",
      "---Online Algorithm Controller Initializing---\n",
      "---Online Algorithm Controller Initialized---\n",
      "- Algorithm: <class '__main__.ThompsonSamping'>\n",
      "- Total steps: 10000\n",
      "---OAC: Running algorithm <class '__main__.ThompsonSamping'> ---\n",
      "- Step: 1000 / 10000\n",
      "- Current avg sum: 26.99446694698128\n",
      "- Step: 2000 / 10000\n",
      "- Current avg sum: 19.924121770440266\n",
      "- Step: 3000 / 10000\n",
      "- Current avg sum: 16.777657945616372\n",
      "- Step: 4000 / 10000\n",
      "- Current avg sum: 14.883338997238539\n",
      "- Step: 5000 / 10000\n",
      "- Current avg sum: 13.674855025718186\n",
      "- Step: 6000 / 10000\n",
      "- Current avg sum: 12.826662895811658\n",
      "- Step: 7000 / 10000\n",
      "- Current avg sum: 12.315267152562187\n",
      "- Step: 8000 / 10000\n",
      "- Current avg sum: 11.807647656136979\n",
      "- Step: 9000 / 10000\n",
      "- Current avg sum: 11.580277874274689\n",
      "- Step: 10000 / 10000\n",
      "- Current avg sum: 11.360502132510998\n",
      "---OAC: Algorithm <__main__.ThompsonSamping object at 0x10ec6b8d0> finished---\n",
      "---OAC: Running algorithm <class '__main__.ThompsonSamping'> ---\n",
      "- Step: 1000 / 10000\n",
      "- Current avg sum: 26.296419566921394\n",
      "- Step: 2000 / 10000\n",
      "- Current avg sum: 19.434424039025537\n",
      "- Step: 3000 / 10000\n",
      "- Current avg sum: 16.21572231150922\n",
      "- Step: 4000 / 10000\n",
      "- Current avg sum: 14.491738904340307\n",
      "- Step: 5000 / 10000\n",
      "- Current avg sum: 13.272284423683043\n",
      "- Step: 6000 / 10000\n",
      "- Current avg sum: 12.638084712955582\n",
      "- Step: 7000 / 10000\n",
      "- Current avg sum: 12.054842679475266\n",
      "- Step: 8000 / 10000\n",
      "- Current avg sum: 11.518204693412587\n",
      "- Step: 9000 / 10000\n",
      "- Current avg sum: 11.240963455391032\n",
      "- Step: 10000 / 10000\n",
      "- Current avg sum: 10.949397105183932\n",
      "---OAC: Algorithm <__main__.ThompsonSamping object at 0x10ec6b898> finished---\n",
      "---OAC: Running algorithm <class '__main__.ThompsonSamping'> ---\n",
      "- Step: 1000 / 10000\n",
      "- Current avg sum: 29.253497802721572\n",
      "- Step: 2000 / 10000\n",
      "- Current avg sum: 20.84193480409794\n",
      "- Step: 3000 / 10000\n",
      "- Current avg sum: 17.34666902198751\n",
      "- Step: 4000 / 10000\n",
      "- Current avg sum: 15.791284072558192\n",
      "- Step: 5000 / 10000\n",
      "- Current avg sum: 14.34810508924121\n",
      "- Step: 6000 / 10000\n",
      "- Current avg sum: 13.690738309572811\n",
      "- Step: 7000 / 10000\n",
      "- Current avg sum: 13.065879603109087\n",
      "- Step: 8000 / 10000\n",
      "- Current avg sum: 12.433857369755284\n",
      "- Step: 9000 / 10000\n",
      "- Current avg sum: 12.082839215194804\n",
      "- Step: 10000 / 10000\n",
      "- Current avg sum: 11.829113714457169\n",
      "---OAC: Algorithm <__main__.ThompsonSamping object at 0x10ec6b9e8> finished---\n",
      "---OAC: Running algorithm <class '__main__.ThompsonSamping'> ---\n",
      "- Step: 1000 / 10000\n",
      "- Current avg sum: 27.590571955560275\n",
      "- Step: 2000 / 10000\n",
      "- Current avg sum: 19.484283769478168\n",
      "- Step: 3000 / 10000\n",
      "- Current avg sum: 16.558833116758866\n",
      "- Step: 4000 / 10000\n",
      "- Current avg sum: 14.68398571504792\n",
      "- Step: 5000 / 10000\n",
      "- Current avg sum: 13.448660769351543\n",
      "- Step: 6000 / 10000\n",
      "- Current avg sum: 12.644181834781929\n",
      "- Step: 7000 / 10000\n",
      "- Current avg sum: 12.096696903085922\n",
      "- Step: 8000 / 10000\n",
      "- Current avg sum: 11.530697548230693\n",
      "- Step: 9000 / 10000\n",
      "- Current avg sum: 11.271639464023933\n",
      "- Step: 10000 / 10000\n",
      "- Current avg sum: 10.995898618886041\n",
      "---OAC: Algorithm <__main__.ThompsonSamping object at 0x10ec6b940> finished---\n",
      "---OAC: Running algorithm <class '__main__.ThompsonSamping'> ---\n",
      "- Step: 1000 / 10000\n",
      "- Current avg sum: 25.922835542995074\n",
      "- Step: 2000 / 10000\n",
      "- Current avg sum: 18.647057115874052\n",
      "- Step: 3000 / 10000\n",
      "- Current avg sum: 15.720768767803118\n",
      "- Step: 4000 / 10000\n",
      "- Current avg sum: 14.07381768447631\n",
      "- Step: 5000 / 10000\n",
      "- Current avg sum: 12.961153116971682\n",
      "- Step: 6000 / 10000\n",
      "- Current avg sum: 12.218207236143964\n",
      "- Step: 7000 / 10000\n",
      "- Current avg sum: 11.70721307396121\n",
      "- Step: 8000 / 10000\n",
      "- Current avg sum: 11.186216118829204\n",
      "- Step: 9000 / 10000\n",
      "- Current avg sum: 10.957315325050592\n",
      "- Step: 10000 / 10000\n",
      "- Current avg sum: 10.682702798503946\n",
      "---OAC: Algorithm <__main__.ThompsonSamping object at 0x10ec6ba90> finished---\n",
      "---OAC: Running algorithm <class '__main__.ThompsonSamping'> ---\n",
      "- Step: 1000 / 10000\n",
      "- Current avg sum: 30.406027871905753\n",
      "- Step: 2000 / 10000\n",
      "- Current avg sum: 22.231738643496648\n",
      "- Step: 3000 / 10000\n",
      "- Current avg sum: 18.18296809022303\n",
      "- Step: 4000 / 10000\n",
      "- Current avg sum: 16.093168669657835\n",
      "- Step: 5000 / 10000\n",
      "- Current avg sum: 14.701913849284336\n",
      "- Step: 6000 / 10000\n",
      "- Current avg sum: 13.879195606872601\n",
      "- Step: 7000 / 10000\n",
      "- Current avg sum: 13.276678072619644\n",
      "- Step: 8000 / 10000\n",
      "- Current avg sum: 12.63534569464944\n",
      "- Step: 9000 / 10000\n",
      "- Current avg sum: 12.280077352750464\n",
      "- Step: 10000 / 10000\n",
      "- Current avg sum: 12.023301899143823\n",
      "---OAC: Algorithm <__main__.ThompsonSamping object at 0x10ec00710> finished---\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "v1 = 0.01\n",
    "v2 = 0.05\n",
    "v3 = 0.1\n",
    "v4 = 0.5\n",
    "v5 = 1\n",
    "v6 = 5\n",
    "\n",
    "ts_1 = ThompsonSamping(M, S, v1)\n",
    "ts_2 = ThompsonSamping(M, S, v2)\n",
    "ts_3 = ThompsonSamping(M, S, v3)\n",
    "ts_4 = ThompsonSamping(M, S, v4)\n",
    "ts_5 = ThompsonSamping(M, S, v5)\n",
    "ts_6 = ThompsonSamping(M, S, v6)\n",
    "\n",
    "oacTS_1  = OnlineAlgorithmController(ts_1, tasks, mus, zts, TCount, positions, mc)\n",
    "oacTS_2  = OnlineAlgorithmController(ts_2, tasks, mus, zts, TCount, positions, mc)\n",
    "oacTS_3  = OnlineAlgorithmController(ts_3, tasks, mus, zts, TCount, positions, mc)\n",
    "oacTS_4  = OnlineAlgorithmController(ts_4, tasks, mus, zts, TCount, positions, mc)\n",
    "oacTS_5  = OnlineAlgorithmController(ts_5, tasks, mus, zts, TCount, positions, mc)\n",
    "oacTS_6  = OnlineAlgorithmController(ts_6, tasks, mus, zts, TCount, positions, mc)\n",
    "\n",
    "cost_ts_1  = oacTS_1.run_all(gap)\n",
    "cost_ts_2  = oacTS_2.run_all(gap)\n",
    "cost_ts_3  = oacTS_3.run_all(gap)\n",
    "cost_ts_4  = oacTS_4.run_all(gap)\n",
    "cost_ts_5  = oacTS_5.run_all(gap)\n",
    "cost_ts_6  = oacTS_6.run_all(gap)\n",
    "\n",
    "\n",
    "plt.title('Result Analysis')\n",
    " \n",
    "plt.plot(xs, cost_ts_1, color='#1177b0', label='v=0.01')\n",
    "plt.plot(xs, cost_ts_2, color='#45b787', label='v=0.05')\n",
    "plt.plot(xs, cost_ts_3, color='#ad9e5f', label='v=0.1')\n",
    "plt.plot(xs, cost_ts_4, color='#61649f', label='v=0.5')\n",
    "plt.plot(xs, cost_ts_5, color='#ba2f7b', label='v=1')\n",
    "plt.plot(xs, cost_ts_6, color='#74787a', label='v=5')\n",
    "plt.legend()\n",
    " \n",
    "plt.xlabel('Learning Slot')\n",
    "plt.ylabel('Average Time Cost')\n",
    "plt.savefig('resultVValue.png')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(xs, cost_ts_1, color='#1177b0', label='v=0.01')\n",
    "plt.plot(xs, cost_ts_2, color='#45b787', label='v=0.05')\n",
    "plt.plot(xs, cost_ts_3, color='#ad9e5f', label='v=0.1')\n",
    "plt.plot(xs, cost_ts_4, color='#61649f', label='v=0.5')\n",
    "plt.plot(xs, cost_ts_5, color='#ba2f7b', label='v=1')\n",
    "plt.plot(xs, cost_ts_6, color='#74787a', label='v=5')\n",
    "plt.legend()\n",
    " \n",
    "plt.xlabel('Learning Slot')\n",
    "plt.ylabel('Average Time Cost')\n",
    "plt.savefig('resultVValue.png', dpi=300)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
